package main

import (
	"errors"
	"fmt"
	"math"
)

/*
创建自定义错误可以使用errors包下的New()函数，以及fmt包下的：Errorf()函数。
*/

func circleArea(radius float64) (float64, error) {
	if radius < 0 {
		return 0, errors.New("错误，半径不能小于0")
	}

	return math.Pi * radius * radius, nil
}

func circleArea1(radius float64) (float64, error) {
	if radius < 0 {
		return 0, fmt.Errorf("半径 %f 不能小于0", radius)
	}

	return math.Pi * radius * radius, nil
}

func main() {
	radius := -20.0
	area, err := circleArea(radius)
	if err != nil {
		fmt.Println(err)
		//return
	}

	fmt.Printf("Area of circle %0.2f", area)

	area1, err := circleArea1(radius)
	if err != nil {
		fmt.Println(err)
		//return
	}

	println(area1)

	area2, err := circleArea2(radius)
	if err != nil {
		fmt.Println(err)
	}

	println(area2)
}

type areaError struct {
	error  string
	radius float64
}

func (e *areaError) Error() string {
	return fmt.Sprintf("radius %0.2f:%s", e.radius, e.error)
}

func (e *areaError) lengthNegaticve() bool {
	return e.radius < 0
}

func circleArea2(radius float64) (float64, error) {
	if radius < 0 {
		return 0, &areaError{"redisu is negative", radius}
	}

	return math.Pi * radius * radius, nil
}

//失败原因只有一个时，直接返回布尔值，不用换使用error
//error 的值应当放在返回值的最后
//错误处理使用defer
//当上层函数不关心错误时，建议不返回error
//当发生错误时，不忽略有用的返回值
